<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>互动白板</title>
  <link rel="stylesheet" href="./lib/bootstrap.min.css" />
  <style>
    .bg-f2 {
      background-color: #f8f9fa;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="my-3 p-3 bg-white rounded box-shadow small">
      <h6 class="border-bottom border-gray pb-2 mb-0">白板基础功能</h6>
      <div class="row" style="margin-top: 1%;">
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="appID"><strong class="text-gray-dark">appID</strong></label>
            </div>
            <input class="form-control d-inline" value="1739272706" style="width: 75%;" type="text" id="appID"
              placeholder="请输入appID" />
          </div>
        </div>
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="server"><strong class="text-gray-dark">server</strong></label>
            </div>
            <input class="form-control d-inline" value="wss://webliveroom-test.zego.im/ws" style="width: 75%;"
              type="text" id="server" placeholder="请输入server" />
          </div>
        </div>
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="idName"><strong class="text-gray-dark">idName</strong></label>
            </div>
            <input class="form-control d-inline" style="width: 75%;" type="text" id="idName" placeholder="请输入idName" />
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="roomID"><strong class="text-gray-dark">roomID</strong></label>
            </div>
            <input class="form-control d-inline" style="width: 75%;" type="text" id="roomID" placeholder="请输入roomID" />
          </div>
        </div>
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="token"><strong class="text-gray-dark">token</strong></label>
            </div>
            <input class="form-control d-inline" style="width: 75%;" type="text" id="token" placeholder="请输入token" />
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm">
          <button type="button" id="init" class="btn btn-primary btn-sm">
            初始化
          </button>
          <button type="button" id="createRoom" class="btn btn-primary btn-sm">
            创建房间
          </button>
          <button type="button" id="openRoom" class="btn btn-primary btn-sm">
            进入房间
          </button>
          <button type="button" id="leaveRoom" class="btn btn-secondary btn-sm">
            退出
          </button>
        </div>
      </div>
      <div class="row" style="margin-top: 1%;">
        <div class="col-sm-5">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend" id="getViewList">
              <label class="input-group-text">
                <strong class="text-gray-dark">获取白板列表</strong>
              </label>
            </div>
            <select id="remoteView" class="form-control d-inline" style="width: 260px;"
              onchange="selectRemoteView(this)"></select>
          </div>
        </div>
        <div class="col-sm-5">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text">
                <strong class="text-gray-dark">Excel Sheets</strong>
              </label>
            </div>
            <select id="excelSheets" class="form-control d-inline" style="width: 260px;"
              onchange="selectExcelSheets(this)"></select>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="aspectWidth"><strong class="text-gray-dark">等比宽</strong></label>
            </div>
            <input class="form-control d-inline" value="5" style="width: 65%;" type="text" id="aspectWidth"
              placeholder="请输入aspectWidth" />
          </div>
        </div>
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="aspectHeight"><strong class="text-gray-dark">等比高</strong></label>
            </div>
            <input class="form-control d-inline" value="3" style="width: 65%;" type="text" id="aspectHeight"
              placeholder="请输入aspectHeight" />
          </div>
        </div>
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="whiteboardName"><strong class="text-gray-dark">白板名称</strong></label>
            </div>
            <input class="form-control d-inline" value="测试白板" style="width: 65%;" type="text" id="whiteboardName"
              placeholder="请输入白板名称" />
          </div>
        </div>
        <div class="col-sm">
          <button type="button" id="createView" class="btn btn-primary btn-sm">
            创建白板
          </button>
        </div>
      </div>
      <pre style="margin-bottom: 0;">tips：多端同步时，aspectWidth、aspectHeight请与白板容器尺寸比例保持一致
      若父容器 宽:高=w:h
        创建单页白板 aspectWidth=w，aspectHeight=h
        创建m页横向白板 aspectWidth=w*m，aspectHeight=h
        创建m页纵向白板 aspectWidth=w，aspectHeight=h*m
        创建文件白板，不区分方向，固定 aspectWidth=w，aspectHeight=h*m
      </pre>
      <div class="row">
        <div class="col-sm">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="fileID"><strong class="text-gray-dark">文件ID</strong></label>
            </div>
            <input class="form-control d-inline" readonly style="width: 65%;" type="text" id="fileID"
              placeholder="文件ID" />
          </div>
        </div>
        <div class="col-sm-5">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text">
                <strong class="text-gray-dark">文件列表</strong>
              </label>
            </div>
            <select id="fileType" class="form-control d-inline" style="width: 260px;" onchange="onFileIdChange(this)">
              <option value="">--</option>
              <option value="Z6SfBhPNkHuGYQwV">jpg</option>
              <option value="bO_ptIYGusHPa3Uq">jpeg</option>
              <option value="xAKHOEjtpHRFQAJi">png</option>
              <option value="-gu5ZUA7TlrRbA-E">bmp</option>
              <option value="d0KvOFgae0kt3w5R">ppt</option>
              <option value="OuRCC82ojjnt0yGb">pdf</option>
              <option value="YI_H8iLnoF0iRghn">doc</option>
              <option value="OgG3AKuEdWGwW4H0">txt</option>
              <option value="iUrfzJ6PM3R04l3u">xls</option>
              <option value="NLQDz-6SGveZKCOq">动态PPT</option>
            </select>
          </div>
        </div>
        <div class="col-sm">
          <button id="createFileView" class="btn btn-primary btn-sm"">创建文件白板</button>
        </div>
      </div>
      <div class=" row">
        <div class="col-sm">
          <button id="path" type="button" class="btn btn-primary btn-sm">
            涂鸦
          </button>
          <button id="text" type="button" class="btn btn-primary btn-sm">
            文本
          </button>
          <button id="line" type="button" class="btn btn-primary btn-sm">
            直线
          </button>
          <button id="rect" type="button" class="btn btn-primary btn-sm">
            矩形
          </button>
          <button id="ellipse" type="button" class="btn btn-primary btn-sm">
            椭圆
          </button>
          <button id="selector" type="button" class="btn btn-primary btn-sm">
            选择
          </button>
          <button id="eraser" type="button" class="btn btn-primary btn-sm">
            橡皮擦
          </button>
          <button id="undo" type="button" class="btn btn-primary btn-sm">
            撤销
          </button>
          <button id="redo" type="button" class="btn btn-primary btn-sm">
            重做
          </button>
          <button id="clear" type="button" class="btn btn-secondary btn-sm">
            清空图元
          </button>
        </div>
      </div>
      <div class="row" style="margin-top: 1%;">
        <div class="col-sm-3">
          <div class="input-group input-group-sm mb-3">
            <div class="input-group-prepend">
              <label class="input-group-text" for="curPage"><strong class="text-gray-dark">当前页</strong></label>
            </div>
            <input class="form-control d-inline" value="1" readonly style="width: 65%;" type="text" id="curPage"
              placeholder="当前页" />
          </div>
        </div>
        <div class="col-sm">
          <button id="previousPage" type="button" class="btn btn-primary btn-sm">上一页</button>
          <button id="nextPage" type="button" class="btn btn-primary btn-sm">下一页</button>
        </div>
      </div>      
      <div class="row" style="margin-top: 1%;">
        <div class="col-sm">
          <h6 class="pb-2 mb-0">
            白板容器（1000 * 600）
          </h6>
          <div id="mywhiteboard" style="width: 1000px; height: 600px; border: 1px dashed #ddd;position: relative;">
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
<script src="./lib/jquery-3.3.1.min.js"></script>
<script src="./ZegoExpress.js"></script>
<script src="./ZegoExpressDocs.js"></script>
<script>
  var zg,
    isLogin = false,
    parentId = 'mywhiteboard',
    zgViewList = [],
    zgWbView,
    zgDocsViewClient,
    zgDocsView,
    excelWBMap = {},
    isRemote;
  $("#idName").val(new Date().getTime() + '');

  // 获取token
  const tokenUrl = 'https://wsliveroom-alpha.zego.im:8282/token';
  $.get(
    tokenUrl,
    {
      app_id: $("#appID").val(),
      id_name: $("#idName").val()
    },
    function (token) {
      if (!token) {
        alert('get token failed');
      } else {
        $("#token").val(token);
        alert('get token success');
      }
    },
    'text'
  );

  // 监听sdk回调
  function listen() {
    zg.on("error", (errorData) => {
      console.log("on error");
      console.log(errorData);
    });
    zg.on("viewAdd", (wbView) => {
      console.log("on viewAdd");
      console.log(wbView);
    });
    zg.on("viewRemoved", (whiteboardID) => {
      console.log("on viewRemoved");
      console.log(`whiteboardID: ${whiteboardID}`);
    });
    zg.on(
      "viewScroll",
      (whiteboardID, horizontalPercent, verticalPercent, page) => {
        console.log("on viewScroll");
        console.log(whiteboardID);
        console.log(horizontalPercent);
        console.log(verticalPercent);
        console.log(page);
        page && (document.getElementById('curPage').value = page);
      }
    );
    zgDocsViewClient.on('onLoadFile', async function (res) {
      const { fileID, fileType, fileName, viewID, authKey, pageCount } = res;
      if (!isRemote) {
        zg.createView({
          roomID: document.getElementById('roomID').value,
          name: fileName,
          aspectWidth: Number(document.getElementById('aspectWidth').value),
          aspectHeight: Number(document.getElementById('aspectHeight').value),
          pageCount,
          fileInfo: { fileID, fileName, fileType, authKey }
        }).then(async function (view) {
          const flag = zgViewList.some(function (v) {
            const file = v.getFileInfo();
            return file && file.fileID === fileID;
          });
          if (!flag) {
            zgWbView = view;
            zgViewList.push(zgWbView);
            await zg.attachView(zgWbView, viewID);
          }
          // Excel Sheet
          if (fileType === 4) {
            excelWBMap[fileID] = excelWBMap[fileID] || { _ids_: '' };
            excelWBMap[fileID][fileName] = view;
            excelWBMap[fileID]._ids_ += view.getID() + ',';
          }
        });
      } else {
        // Excel Sheet
        if (fileType === 4) {
          excelWBMap[fileID] = excelWBMap[fileID] || { _ids_: '' };
          excelWBMap[fileID][fileName] = zgWbView;
          excelWBMap[fileID]._ids_ += zgWbView.getID() + ',';
        }
        await zg.attachView(zgWbView, viewID);
      }
      console.log('docsview onLoadFile', isRemote, fileName, excelWBMap, res);
    });
  }

  function init(appID, server) {
    if (!appID) {
      alert("请输入appID");
      return;
    }

    if (!server) {
      alert("请输入server");
      return;
    }

    zg = new ZegoExpressEngine(appID, server);
    zg.setLogConfig({ logLevel: 3 });

    zgDocsViewClient = new ZegoExpressDocs({
      appID: appID,
      token: '',
      userID: idName,
      isTestEnv: true // 测试环境
    });


    listen();
  }

  function leaveRoom() {
    alert("leave room");
    isLogin = false;
    zg.logoutRoom();
  }

  function openRoom(idName, roomID, token) {
    if (isLogin) {
      return leaveRoom();
    }

    if (!roomID) {
      alert("请输入roomID");
      return;
    }

    if (!token) {
      alert("请输入token");
      return;
    }

    if (!idName) {
      alert("请输入idName");
      return;
    }

    //login
    async function startLogin() {
      try {
        await zg.loginRoom(
          roomID,
          token,
          {
            userID: idName, userName: 'nick' + idName
          },
          {
            maxMemberCount: 3,
            userUpdate: true
          }
        );
      } catch (error) {
        console.log(error);
      }
      alert('登录成功');
    }
    startLogin();
  }

  $(function () {
    $("#init").click(function () {
      init(Number($("#appID").val()), $("#server").val());
    });

    $("#createRoom").click(function () {
      openRoom($("#idName").val(), $("#roomID").val(), $("#token").val());
    });

    $("#openRoom").click(function () {
      openRoom($("#idName").val(), $("#roomID").val(), $("#token").val());
    });

    $("#leaveRoom").click(function () {
      leaveRoom();
    });

    $("#getViewList").click(async function () {
      try {
        list = await zg.getViewList();
        zgViewList = [];
        if (list && list.length) {
          // excel sheets 只显示一个
          const map = {};
          let html = '';
          list.forEach(function(v) {
            const id = v.getID();
            const file = v.getFileInfo();
            if (file && file.fileType === 4) {
              const fileID = file.fileID;
              excelWBMap[fileID] = excelWBMap[fileID] || { _ids_: '' };
              excelWBMap[fileID][file.fileName] = v;
              excelWBMap[fileID]._ids_ += id + ',';
              if (map[fileID]) return;
              map[fileID] = true;
            }
            html += '<option value=' + id + '>' + id + '-' + v.getName() + '</option>';
            zgViewList.push(v);
          });
          document.getElementById('remoteView').innerHTML = '<option>--</option>' + html;
          console.log('docsview getViewList', excelWBMap);
        } else {
          document.getElementById('remoteView').innerHTML = '';
        }
        alert("获取成功");
      } catch (error) {
        console.log(error);
      }
    });

    $("#createView").click(async function () {
      try {
        zgWbView = await zg.createView({
          roomID: document.getElementById("roomID").value,
          name: document.getElementById("whiteboardName").value,
          aspectWidth: Number(document.getElementById("aspectWidth").value),
          aspectHeight: Number(document.getElementById("aspectHeight").value),
        });
        await zg.attachView(zgWbView, parentId);
        zgViewList.push(zgWbView);
        zgDocsView = null;
        alert("创建成功");
      } catch (error) {
        console.log(error);
      }
    });

    $("#createFileView").click(async function () {
      try {
        // 同一个fileID只能创建一个白板（Excel时每个sheet都创建一个白板）
        const fileID = document.getElementById('fileID').value;
        const view = zgViewList.find(function(v) {
          const file = v.getFileInfo();
          return file && file.fileID === fileID;
        });
        if (view) {
          isRemote = true;
          zgWbView = view;
          zgDocsView = zgDocsViewClient.createView(parentId, view.getID(), view.getFileInfo().fileName);
          await zgDocsView.loadFile(fileID, '');
          return;
        }
        isRemote = false;
        zgDocsView = zgDocsViewClient.createView(parentId);
        await zgDocsView.loadFile(fileID, '').then(function(res) {
          const excelDom = document.getElementById('excelSheets');
          // Excel每个sheet都创建一个白板
          if (res.fileType == 4) {
            
            const sheets = res.file_list.map(function(v, i) {
              const name = v.file_name.replace(/.pdf/, "");
              if (i > 0) {
                const view = zgDocsViewClient.createView(parentId, '', name);
                view.loadFile(fileID, '');
              }
              return '<option value="' + name + '">' + name + '</option>';
            });
            if (!excelDom.innerHTML) {
              excelDom.innerHTML = sheets.join('');
            }
          } else {
            excelDom.innerHTML = '';
          }
        });
      } catch (error) {
        console.log(error);
      }
    });

    $("#previousPage").click(async function () {
      zgWbView.scroll((zgWbView.getPage() - 2) / zgWbView.getPageCount(), 0);
      if (zgDocsView) {
        const page = zgDocsView.getCurrentPage();
        if (page > 1) zgDocsView.flipPage(page - 1);
      }
      document.getElementById('curPage').value = zgWbView.getPage();
    });

    $("#nextPage").click(async function () {
      zgWbView.scroll(zgWbView.getPage() / zgWbView.getPageCount(), 0);
      if (zgDocsView) {
        const page = zgDocsView.getCurrentPage();
        if (page < zgDocsView.getPageCount()) zgDocsView.flipPage(page + 1);
      }
      document.getElementById('curPage').value = zgWbView.getPage();
    });

    $("#undo").click(function () {
      zgWbView.undo();
    });

    $("#redo").click(function () {
      zgWbView.redo();
    });

    $("#clear").click(function () {
      zgWbView.clear();
    });

    $("#path").click(function () {
      zgWbView.setToolType(1);
    });

    $("#text").click(function () {
      zgWbView.setToolType(2);
    });

    $("#line").click(function () {
      zgWbView.setToolType(4);
    });

    $("#rect").click(function () {
      zgWbView.setToolType(8);
    });

    $("#ellipse").click(function () {
      zgWbView.setToolType(16);
    });

    $("#selector").click(function () {
      zgWbView.setToolType(32);
    });

    $("#eraser").click(function () {
      zgWbView.setToolType(64);
    });
  });

  async function selectRemoteView(target) {
    const id = target.value;
    if (id) {
      zgWbView = zgViewList.filter(function (v) {
        return id === v.getID();
      })[0];
      if (!zgWbView) {
        alert('远端白板不存在');
        return;
      }
      const fileInfo = zgWbView.getFileInfo();
      if (fileInfo) {
        isRemote = true;
        zgDocsView = zgDocsViewClient.createView(parentId, id, fileInfo.fileName);
        await zgDocsView.loadFile(fileInfo.fileID, fileInfo.authKey);
        document.getElementById('fileID').value = fileInfo.fileID;
        console.log('docsview selectRemoteView', fileInfo.fileName, id);
      } else {
        zgDocsView = null;
        await zg.attachView(zgWbView, parentId);
      }

      document.getElementById('curPage').value = zgWbView.getPage();
    }
    console.log('selectRemoteView', id);
  }

  function onFileIdChange(target) {
    document.getElementById('fileID').value = target.value;
  }

  async function selectExcelSheets(target) {
    const name = target.value;
    const fileID = document.getElementById('fileID').value;
    const view = excelWBMap[fileID][name];
    if (view) {
      isRemote = true;
      zgWbView = view;
      zgDocsView = zgDocsViewClient.createView(parentId, view.getID(), name);
      await zgDocsView.loadFile(fileID, '');
      console.log('docsview selectExcelSheets', isRemote, fileID, name, view && view.getID());
    }
  }
</script>

</html>